import { useEffect, useRef, useState, useMemo, useCallback } from 'react';
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { Button, Select, Space, Tooltip } from 'antd';
import {
  RotateLeftOutlined,
  RotateRightOutlined,
  ZoomInOutlined,
  ZoomOutOutlined,
  ReloadOutlined,
} from '@ant-design/icons';
import styles from './style.module.scss';

// 定义SimpleModelViewer组件的props接口
interface SimpleModelViewerProps {
  modelPath: string;
  scale?: number;
  position?: [number, number, number];
  animationName?: string;
  animationSpeed?: number;
  lang?: 'zh' | 'en';
  onAnimationChange?: (anim: string) => void;
}

// 定义SimpleModelViewer组件
const SimpleModelViewer: React.FC<SimpleModelViewerProps> = ({
  modelPath,
  scale = 1,
  position = [0, 0, 0],
  animationName = 'idle',
  animationSpeed = 1,
  lang = 'zh',
  onAnimationChange,
}) => {
  // 定义ref
  const containerRef = useRef<HTMLDivElement>(null);
  const sceneRef = useRef<THREE.Scene | null>(null);
  const cameraRef = useRef<THREE.PerspectiveCamera | null>(null);
  const rendererRef = useRef<THREE.WebGLRenderer | null>(null);
  const mixerRef = useRef<THREE.AnimationMixer | null>(null);
  const modelRef = useRef<THREE.Group | null>(null);
  const actionsRef = useRef<{ [key: string]: THREE.AnimationAction }>({});
  const currentActionRef = useRef<THREE.AnimationAction | null>(null);
  const clockRef = useRef<THREE.Clock>(new THREE.Clock());
  const controlsRef = useRef<OrbitControls | null>(null);
  const isInitializedRef = useRef(false);
  
  const [currentAnimation, setCurrentAnimation] = useState(animationName);
  const [activePanel, setActivePanel] = useState<'animation' | 'view' | 'position'>('animation');

  // 使用useMemo优化动画配置，避免每次渲染时重新创建
  const animations = useMemo(() => [
    { value: 'idle', label: lang === 'zh' ? '待机' : 'Idle', icon: '💤' },
    { value: 'dance', label: lang === 'zh' ? '跳舞' : 'Dance', icon: '💃' },
    { value: 'crying', label: lang === 'zh' ? '哭泣' : 'Crying', icon: '😢' },
    { value: 'breakDance', label: lang === 'zh' ? '倒立' : 'Breakdance', icon: '🤸' },
  ], [lang]);

  // 使用useCallback优化动画切换函数
  const handleAnimationChange = useCallback((newAnimation: string) => {
    if (actionsRef.current[newAnimation]) {
      if (currentActionRef.current) {
        currentActionRef.current.stop();
        currentActionRef.current.reset();
      }
      const newAction = actionsRef.current[newAnimation];
      newAction.reset();
      newAction.setEffectiveTimeScale(animationSpeed);
      newAction.play();
      currentActionRef.current = newAction;
      setCurrentAnimation(newAnimation);
      if (onAnimationChange) onAnimationChange(newAnimation);
    }
  }, [animationSpeed, onAnimationChange]);

  // 使用useCallback优化其他事件处理函数
  const handleRotate = useCallback((direction: 'left' | 'right') => {
    if (controlsRef.current && cameraRef.current) {
      const angle = direction === 'left' ? Math.PI / 4 : -Math.PI / 4;
      cameraRef.current.position.applyAxisAngle(new THREE.Vector3(0, 1, 0), angle);
      controlsRef.current.update();
    }
  }, []);

  const handleZoom = useCallback((direction: 'in' | 'out') => {
    if (controlsRef.current && cameraRef.current) {
      const factor = direction === 'in' ? 0.9 : 1.1;
      cameraRef.current.position.multiplyScalar(factor);
      controlsRef.current.update();
    }
  }, []);

  const handleReset = useCallback(() => {
    if (controlsRef.current && cameraRef.current) {
      cameraRef.current.position.set(0, 0.8, 3.7);
      controlsRef.current.update();
    }
  }, []);

  const handlePositionAdjust = useCallback((axis: 'x' | 'y' | 'z', value: number) => {
    if (modelRef.current) {
      const position = modelRef.current.position;
      position[axis] += value;
    }
  }, []);

  // 主要初始化useEffect - 只在modelPath变化时重新初始化场景
  useEffect(() => {
    if (!containerRef.current || isInitializedRef.current) return;

    // 清理旧的canvas
    while (containerRef.current.firstChild) {
      containerRef.current.removeChild(containerRef.current.firstChild);
    }

    // 初始化场景
    const scene = new THREE.Scene();
    sceneRef.current = scene;

    // 初始化相机
    const camera = new THREE.PerspectiveCamera(
      75,
      containerRef.current.clientWidth / containerRef.current.clientHeight,
      0.1,
      1000,
    );
    camera.position.set(0, 0.8, 3.7);
    cameraRef.current = camera;

    // 初始化渲染器
    const renderer = new THREE.WebGLRenderer({
      antialias: true,
      alpha: true,
      preserveDrawingBuffer: true,
    });
    renderer.setSize(containerRef.current.clientWidth, containerRef.current.clientHeight);
    renderer.setClearColor(0x000000, 0);
    renderer.outputColorSpace = THREE.SRGBColorSpace;
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    renderer.shadowMap.enabled = false;
    containerRef.current.appendChild(renderer.domElement);
    rendererRef.current = renderer;

    // 添加光源
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
    scene.add(ambientLight);

    const directionalLight = new THREE.DirectionalLight(0xffffff, 1.2);
    directionalLight.position.set(5, 5, 5);
    directionalLight.castShadow = false;
    scene.add(directionalLight);

    const fillLight = new THREE.DirectionalLight(0xffffff, 0.4);
    fillLight.position.set(-5, 3, -5);
    fillLight.castShadow = false;
    scene.add(fillLight);

    // 添加轨道控制器
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true;
    controls.dampingFactor = 0.05;
    controls.enableZoom = true;
    controls.minDistance = 1;
    controls.maxDistance = 10;
    controls.screenSpacePanning = false;
    controls.maxPolarAngle = Math.PI / 2;
    controlsRef.current = controls;

    // 加载模型
    if (!modelPath) return;

    const loader = new GLTFLoader();
    loader.load(
      modelPath,
      (gltf) => {
        if (!gltf || !gltf.scene) return;

        const model = gltf.scene;
        model.scale.set(scale, scale, scale);
        model.position.set(...position);
        scene.add(model);
        modelRef.current = model;

        // 设置动画
        if (gltf.animations.length > 0) {
          const mixer = new THREE.AnimationMixer(model);
          mixerRef.current = mixer;

          // 创建所有动画动作
          actionsRef.current = {};
          gltf.animations.forEach((clip) => {
            const action = mixer.clipAction(clip);
            action.setEffectiveTimeScale(animationSpeed);
            action.setLoop(THREE.LoopRepeat, Infinity);
            action.clampWhenFinished = false;
            actionsRef.current[clip.name] = action;
          });

          // 播放默认动画
          if (actionsRef.current[animationName]) {
            currentActionRef.current = actionsRef.current[animationName];
            currentActionRef.current.play();
            setCurrentAnimation(animationName);
            if (onAnimationChange) onAnimationChange(animationName);
          }
        }
      },
      undefined,
      (error) => {
        console.error('加载模型失败:', error);
      },
    );

    // 动画循环
    let animationId: number;
    const animate = () => {
      animationId = requestAnimationFrame(animate);

      const delta = clockRef.current.getDelta();

      if (mixerRef.current) {
        mixerRef.current.update(delta);
      }

      if (controlsRef.current) {
        controlsRef.current.update();
      }

      if (rendererRef.current && sceneRef.current && cameraRef.current) {
        rendererRef.current.render(sceneRef.current, cameraRef.current);
      }
    };
    animate();

    // 处理窗口大小变化
    const handleResize = () => {
      if (!containerRef.current || !cameraRef.current || !rendererRef.current) return;

      const width = containerRef.current.clientWidth;
      const height = containerRef.current.clientHeight;

      cameraRef.current.aspect = width / height;
      cameraRef.current.updateProjectionMatrix();
      rendererRef.current.setSize(width, height);
    };
    window.addEventListener('resize', handleResize);

    isInitializedRef.current = true;

    // 清理函数
    return () => {
      if (animationId) {
        cancelAnimationFrame(animationId);
      }

      if (rendererRef.current) {
        rendererRef.current.dispose();
      }

      if (controlsRef.current) {
        controlsRef.current.dispose();
      }

      if (containerRef.current) {
        while (containerRef.current.firstChild) {
          containerRef.current.removeChild(containerRef.current.firstChild);
        }
      }

      window.removeEventListener('resize', handleResize);
      isInitializedRef.current = false;
    };
  }, [modelPath]); // 只在modelPath变化时重新初始化

  // 处理scale和position变化 - 只更新模型属性，不重新创建场景
  useEffect(() => {
    if (modelRef.current) {
      modelRef.current.scale.set(scale, scale, scale);
      modelRef.current.position.set(...position);
    }
  }, [scale, position]);

  // 处理动画切换 - 只切换动画，不重新创建场景
  useEffect(() => {
    if (actionsRef.current[animationName]) {
      if (currentActionRef.current) {
        currentActionRef.current.stop();
        currentActionRef.current.reset();
      }
      const newAction = actionsRef.current[animationName];
      newAction.reset();
      newAction.setEffectiveTimeScale(animationSpeed);
      newAction.play();
      currentActionRef.current = newAction;
      setCurrentAnimation(animationName);
      if (onAnimationChange) onAnimationChange(animationName);
    }
  }, [animationName, animationSpeed, onAnimationChange]);

  // 使用useCallback优化渲染控制面板内容
  const renderPanelContent = useCallback(() => {
    switch (activePanel) {
      case 'animation':
        return (
          <div className={styles.animationSelect}>
            <Select
              value={currentAnimation}
              onChange={handleAnimationChange}
              options={animations}
              optionLabelProp="label"
              className={styles.select}
              styles={{
                popup: {
                  root: { width: 300 }
                }
              }}
              optionRender={(option) => (
                <div className={styles.selectOption}>
                  <span className={styles.optionIcon}>{option.data.icon}</span>
                  <span>{option.data.label}</span>
                </div>
              )}
            />
          </div>
        );
      case 'view':
        return (
          <div className={styles.controlButtons}>
            <Space wrap>
              <Tooltip title={lang === 'zh' ? '向左旋转' : 'Rotate Left'}>
                <Button icon={<RotateLeftOutlined />} onClick={() => handleRotate('left')} />
              </Tooltip>
              <Tooltip title={lang === 'zh' ? '向右旋转' : 'Rotate Right'}>
                <Button icon={<RotateRightOutlined />} onClick={() => handleRotate('right')} />
              </Tooltip>
              <Tooltip title={lang === 'zh' ? '放大' : 'Zoom In'}>
                <Button icon={<ZoomInOutlined />} onClick={() => handleZoom('in')} />
              </Tooltip>
              <Tooltip title={lang === 'zh' ? '缩小' : 'Zoom Out'}>
                <Button icon={<ZoomOutOutlined />} onClick={() => handleZoom('out')} />
              </Tooltip>
              <Tooltip title={lang === 'zh' ? '重置视角' : 'Reset View'}>
                <Button icon={<ReloadOutlined />} onClick={handleReset} />
              </Tooltip>
            </Space>
          </div>
        );
      case 'position':
        return (
          <div className={styles.positionControls}>
            <Space direction="vertical" size="small" style={{ width: '100%' }}>
              <Space>
                <Button size="small" onClick={() => handlePositionAdjust('x', -0.1)}>
                  {lang === 'zh' ? '-X' : '-X'}
                </Button>
                <Button size="small" onClick={() => handlePositionAdjust('x', 0.1)}>
                  {lang === 'zh' ? '+X' : '+X'}
                </Button>
              </Space>
              <Space>
                <Button size="small" onClick={() => handlePositionAdjust('y', -0.1)}>
                  {lang === 'zh' ? '-Y' : '-Y'}
                </Button>
                <Button size="small" onClick={() => handlePositionAdjust('y', 0.1)}>
                  {lang === 'zh' ? '+Y' : '+Y'}
                </Button>
              </Space>
              <Space>
                <Button size="small" onClick={() => handlePositionAdjust('z', -0.1)}>
                  {lang === 'zh' ? '-Z' : '-Z'}
                </Button>
                <Button size="small" onClick={() => handlePositionAdjust('z', 0.1)}>
                  {lang === 'zh' ? '+Z' : '+Z'}
                </Button>
              </Space>
            </Space>
          </div>
        );
    }
  }, [activePanel, currentAnimation, animations, handleAnimationChange, lang, handleRotate, handleZoom, handleReset, handlePositionAdjust]);

  return (
    <div className={styles.modelViewerContainer}>
      <div ref={containerRef} style={{ width: '100%', height: '100%' }} />
      <div className={styles.animationControls}>
        <div className={styles.controlPanel}>
          <div className={styles.panelHeader}>
            <div className={styles.panelTitle}>{lang === 'zh' ? '控制面板' : 'Control Panel'}</div>
            <Space size="small">
              <Button
                type={activePanel === 'animation' ? 'primary' : 'default'}
                size="small"
                onClick={() => setActivePanel('animation')}
              >
                {lang === 'zh' ? '动画' : 'Animation'}
              </Button>
              <Button
                type={activePanel === 'view' ? 'primary' : 'default'}
                size="small"
                onClick={() => setActivePanel('view')}
              >
                {lang === 'zh' ? '视角' : 'View'}
              </Button>
              <Button
                type={activePanel === 'position' ? 'primary' : 'default'}
                size="small"
                onClick={() => setActivePanel('position')}
              >
                {lang === 'zh' ? '位置' : 'Position'}
              </Button>
            </Space>
          </div>
          {renderPanelContent()}
        </div>
      </div>
    </div>
  );
};

export default SimpleModelViewer;
